1 module unde.games.dizzy.omega.fish;
2 
3 import derelict.opengl3.gl;
4 import std.conv;
5 import std.math;
6 import std.format;
7 import std.stdio;
8 import unde.games.object;
9 import unde.games.renderer;
10 import unde.global_state;
11 
12 class Fish:StaticGameObject
13 {
14     static int num;
15     int number;
16     
17     int hidden;
18 
19     enum SPEED = 0.1;
20     enum MAX_V = 0.3;
21     enum JUMP_V = 0.2;
22     enum A = 0.01;
23     enum G = 0.004;
24 
25     float def_x, def_y, def_z;
26     float dx = 0.0, dy = 0.0;
27     float lx, rx, ty, gy;
28     float size;
29     float kspeed;
30 
31     ulong delay;
32     
33     this(MainGameObject root, float[3] coords, float lx, float rx,
34         float size, float speed, float gy = float.nan, ulong delay = 0)
35     {
36         def_x = x = coords[0];
37         def_y = y = coords[1];
38         def_z = z = coords[2];
39 
40         this.lx = lx;
41         this.rx = rx;
42         this.size = size;
43         this.gy = gy;
44         this.delay = delay;
45         kspeed = speed;
46         number = num++;
47         dx = SPEED*kspeed;
48 
49         if (!gy.isNaN) dy = JUMP_V;
50         
51         super(root);
52     }
53 
54     void hide()
55     {
56         hidden = true;
57     }
58 
59     override void draw(GlobalState gs)
60     {
61         if (!hidden && abs(x-root.scrx) < 32.0 &&
62             abs(root.scry-y) < 18.0)
63         {
64             uint rf = cast(uint)(root.frame/7.5);
65             uint frame = 0;
66             if (rf % 8 == 1)
67                 frame = 1;
68             if (rf % 8 == 2)
69                 frame = 2;
70             if (rf % 8 == 3)
71                 frame = 1;
72             if (rf % 8 == 5)
73                 frame = 3;
74             if (rf % 8 == 6)
75                 frame = 4;
76             if (rf % 8 == 7)
77                 frame = 3;
78 
79             glPushMatrix();
80             glTranslatef(x, y, z);
81             if (dx < 0.0) glRotatef(180,0,1,0);
82             glRotatef(atan2(dy, 0.1f)*180/PI,0,0,1);
83             glScalef(size, size, size);
84             recursive_render(gs, root.models["fish-"~frame.to!(string)]);
85             glPopMatrix();
86         } 
87     }    
88 
89     override bool tick(GlobalState gs)
90     {
91         if ( hidden || abs(root.scrx-x) > 16.0 &&
92              abs(root.scrx-def_x) > 16.0 ||
93              abs(root.scry-y) > 18.0 )
94             return true;
95 
96         frame++;
97         if (frame < delay) return true;
98             
99         x += dx;
100         y += dy;
101 
102         if (!gy.isNaN)
103         {
104             if (y > gy) dy -= G;
105             if (dy < -MAX_V) dy = -MAX_V;
106             if (dy < 0 && y <= gy+.2)
107                 dy = (gy - y)*MAX_V;
108         }
109         else
110         {
111             if (x > rx)
112                 dx = -SPEED*kspeed;
113             if (x < lx)
114                 dx = SPEED*kspeed;
115         }
116         return true;
117     }
118 
119     override void load(string[string] s)
120     {
121         string p = "fish"~number.to!(string);
122         if (p~"-x" in s)
123             x = s[p~"-x"].to!(float);
124         else
125             x = def_x;
126             
127         if (p~"-y" in s)
128             y = s[p~"-y"].to!(float);
129         else
130             y = def_y;
131             
132         if (p~"-z" in s)
133             z = s[p~"-z"].to!(float);
134         else
135             z = def_z;
136 
137         if (p~"-dx" in s)
138             dx = s[p~"-dx"].to!(float);
139         else
140             dx = SPEED*kspeed;
141 
142         if (p~"-dy" in s)
143             dy = s[p~"-dy"].to!(float);
144         else
145         {
146             dy = 0.0;
147             if (!gy.isNaN) dy = JUMP_V;
148         }
149 
150         frame = 0;
151 
152         if (p in s)
153         {
154             hidden = (s[p] == "hidden")?1:0;
155         }
156         else
157         {
158             hidden = 0;
159         }
160     }
161 
162     override void save(ref string[string] s)
163     {
164         string p = "fish"~number.to!(string);
165         if (hidden == 1)
166             s[p] = "hidden";
167 
168         s[p~"-x"] = x.to!(string);
169         s[p~"-y"] = y.to!(string);
170         s[p~"-z"] = z.to!(string);
171         s[p~"-dx"] = dx.to!(string);
172         s[p~"-dy"] = dy.to!(string);
173         s[p~"-state"] = state.to!(string);
174 
175     }    
176 }